export default class DynamicLibLoader {
  libraryCache: Map<string, ScriptFetcher> = new Map()
  constructor() {}
  load(e: string, t?: keyof Window) {
    const i = this.libraryCache.get(e) || new ScriptFetcher(e, t)
    this.libraryCache.set(e, i)
    return i.library
  }
}
class ScriptFetcher {
  libraryResolver: Function | undefined
  libraryRejecter: Function | undefined
  _libraryPromise: Promise<any>
  constructor(e: RequestInfo, t?: keyof Window) {
    this._libraryPromise = new Promise((resolve, reject) => {
      this.libraryResolver = resolve
      this.libraryRejecter = reject
    })
    this.fetch(e, t)
  }
  async fetch(e: RequestInfo, t?: keyof Window) {
    let i: Response
    try {
      i = await fetch(new Request(e, {}))
    } catch (e) {
      return this.libraryRejecter?.(e)
    }
    if (!i.ok) return this.libraryRejecter?.("Script not found.")
    const n = {}
    const s = await i.text()
    new Function(s).call(n)
    if (t && t in window) {
      const e = window[t] || {}
      Object.assign(n, e)
      delete window[t]
    }
    this.libraryResolver?.(n)
  }
  get library() {
    return this._libraryPromise
  }
}
